package wangwenjun.phase2.concurrencypattern.eventrouter.demo03.framework;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author ChangLiang
 * @date 2020/6/20
 */
public class AsyncRouter implements IRouter<Message> {

    private final Map<Class<? extends Message>,AsyncChannel> routerTable;

    /**
     * 并发安全 此时多线程registerChannel就安全了
     */
    public AsyncRouter() {
        this.routerTable = new ConcurrentHashMap<>();
    }

    @Override
    public void registerChannel(Class<? extends Message> messageType, Channel<? extends Message> channel) {
        if (!(channel instanceof AsyncChannel)) {
            throw new IllegalArgumentException("the channel must be AsyncChannel Type");
        }
        this.routerTable.put(messageType, (AsyncChannel) channel);
    }

    @Override
    public void dispatch(Message message) {
        if (routerTable.containsKey(message.getType())) {
            routerTable.get(message.getType()).dispatch(message);
        } else {
            throw new NoMatchedChannelException("cannot find the matched channel for message type:[" + message.getType() +"}]");
        }
    }

    public void shutdown() {
        routerTable.values().forEach(AsyncChannel::stop);
    }
}
